package com.cloudfun.campusshare.device.protocol.command;

import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.util.ByteUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * 滚筒洗衣机
 * Created by Huqin on 2020/1/15
 */
public class GxyCommandFactory extends CommandFactory {

    public static final Map<String, String> washTypeMap = new HashMap<>();

    static {
        washTypeMap.put("1", "1F");//冷水（标准）
        washTypeMap.put("2", "20");//温水（快速）
        washTypeMap.put("3", "21");//热水（大物）
        washTypeMap.put("4", "1C");//单脱
        washTypeMap.put("5", "0D");//桶自洁
        washTypeMap.put("8", "22");//轻柔
    }

    /**
     * 强力去污功能开启
     *
     * @return
     */
    public Frame enableDecontamination() {
        return new Frame((byte) 1, ByteUtil.hexStringToByte("4d14"));
    }

    /**
     * 强力去污功能关闭
     *
     * @return
     */
    public Frame disableDecontamination() {
        return new Frame((byte) 1, ByteUtil.hexStringToByte("4d15"));
    }

    /**
     * 动态验证码
     * 验证码(4bytes)
     *
     * @return
     */
    public Frame dynamicVerifyCode(String code) {
        return new Frame((byte) 1, ByteUtil.hexStringToByte("4d1D" + code));
    }

    /**
     * 组命令帧
     *
     * @param washType              0Dh对应着“筒自洁”
     *                              1Ch对应着“单脱”
     *                              1Fh对应着“冷水（标准）”
     *                              20h对应着“温水（快速）”
     *                              21h对应着“热水（大物）”
     *                              22h对应着“轻柔” 8公斤滚筒洗衣机不支持
     * @param heat40                开启40℃加热
     * @param heat60                开启60℃加热
     * @param quietRinseStatus      开启超净漂洗功能
     * @param strongDecontamination 开启强力去污功能
     * @return
     */
    public Frame washGroupCommand(String washType, boolean heat40, boolean heat60, boolean quietRinseStatus, boolean strongDecontamination, boolean addLaundryDetergent) {
        return this.washGroupCommand(washType, getAddFunc(heat40, heat60, quietRinseStatus, strongDecontamination, addLaundryDetergent));
    }

    /**
     * 组命令帧
     *
     * @param washType 0Dh对应着“筒自洁”
     *                 1Ch对应着“单脱”
     *                 1Fh对应着“冷水（标准）”
     *                 20h对应着“温水（快速）”
     *                 21h对应着“热水（大物）”
     *                 22h对应着“轻柔” 8公斤滚筒洗衣机不支持
     * @param addFunc
     * @return
     */
    public Frame washGroupCommand(String washType, byte[] addFunc) {
        if (!washTypeMap.containsKey(washType)) {
            throw new BusinessException(Code.PARAMETER_ERROR);
        }
        String washTypeCode = washTypeMap.get(washType);
        // 子命令类型
        byte[] subCommandType = new byte[]{0, 1};
        // 参数1 洗衣程序
        byte[] washTypeBytes = ByteUtil.hexStringToByte(washTypeCode);
        washTypeBytes = new byte[]{0, washTypeBytes[washTypeBytes.length - 1]};

        byte[] params = new byte[30];
        // 参数1 洗衣程序
        int position = 0;
        System.arraycopy(washTypeBytes, 0, params, position, washTypeBytes.length);
        position += washTypeBytes.length;
        // 参数2-3 预留
        for (int i = 0; i < 2; i++) {
            position += 2;
        }
        // 参数4
        System.arraycopy(addFunc, 0, params, position, addFunc.length);
        position += addFunc.length;
        // 参数5-15 预留
        for (int i = 0; i < 11; i++) {
            position += 2;
        }
        return groupCommand(subCommandType, params);
    }

    /**
     * 组命令附加控制功能
     *
     * @param heat40                开启40℃加热
     * @param heat60                开启60℃加热
     * @param quietRinseStatus      开启超净漂洗功能
     * @param strongDecontamination 开启强力去污功能
     * @param strongDecontamination 开启添加洗衣液
     * @return
     */
    public static byte[] getAddFunc(boolean heat40, boolean heat60, boolean quietRinseStatus, boolean strongDecontamination, boolean addLaundryDetergent) {
        byte res = 0;
        if (heat40) {
            res |= 1 << 7;
        }
        if (heat60) {
            res |= 1 << 6;
        }
        if (quietRinseStatus) {
            res |= 1 << 5;
        }
        if (strongDecontamination) {
            res |= 1 << 4;
        }
        if (addLaundryDetergent) {
            res |= 1 << 3;
        }
        return new byte[]{0, res};
    }
}
